<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON 差异对比测试</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        
        .test-container {
            background: white;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .test-title {
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 15px;
            color: #333;
        }
        
        .test-description {
            color: #666;
            margin-bottom: 15px;
            font-size: 14px;
        }
        
        .test-input {
            width: 100%;
            min-height: 100px;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 12px;
            margin-bottom: 10px;
        }
        
        .test-button {
            background: #667eea;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            margin-right: 10px;
        }
        
        .test-button:hover {
            background: #5a67d8;
        }
        
        .diff-result {
            margin-top: 15px;
            border: 1px solid #e9ecef;
            border-radius: 6px;
            overflow: hidden;
        }
        
        .diff-header {
            background: #f8f9fa;
            padding: 10px 15px;
            border-bottom: 1px solid #e9ecef;
            font-weight: 600;
            font-size: 14px;
        }
        
        .diff-content {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 0;
        }
        
        .diff-section {
            padding: 15px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 12px;
            line-height: 1.4;
            white-space: pre-wrap;
            word-break: break-all;
            max-height: 300px;
            overflow-y: auto;
        }
        
        .diff-section.original {
            background: #fff5f5;
            border-right: 1px solid #e9ecef;
        }
        
        .diff-section.repaired {
            background: #f0fff4;
        }
        
        .diff-stats {
            background: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 6px;
            padding: 10px 15px;
            margin-top: 15px;
            font-size: 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .diff-stat-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .diff-stat-badge {
            padding: 2px 6px;
            border-radius: 10px;
            font-size: 10px;
            font-weight: 600;
            color: white;
        }
        
        .diff-stat-badge.quotes {
            background: #e3f2fd;
            color: #0d47a1;
            border: 1px solid #bbdefb;
        }
        
        .diff-stat-badge.commas {
            background: #f3e5f5;
            color: #4a148c;
            border: 1px solid #e1bee7;
        }
        
        .diff-stat-badge.comments {
            background: #ffebee;
            color: #c62828;
            border: 1px solid #ffcdd2;
        }
        
        .diff-stat-badge.changed {
            background: #fff3cd;
            color: #856404;
            border: 1px solid #ffeaa7;
        }
        
        /* 差异高亮样式 */
        .diff-highlight {
            position: relative;
            background: #fff3cd;
            border-radius: 2px;
            padding: 1px 2px;
            margin: 0 1px;
            transition: all 0.2s ease;
        }
        
        .diff-highlight:hover {
            background: #ffeaa7;
            transform: scale(1.02);
        }
        
        .diff-highlight.added {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        
        .diff-highlight.removed {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
            text-decoration: line-through;
        }
        
        .diff-highlight.changed {
            background: #fff3cd;
            color: #856404;
            border: 1px solid #ffeaa7;
        }
        
        .diff-highlight.quote-fixed {
            background: #e3f2fd;
            color: #0d47a1;
            border: 1px solid #bbdefb;
        }
        
        .diff-highlight.comma-fixed {
            background: #f3e5f5;
            color: #4a148c;
            border: 1px solid #e1bee7;
        }
        
        .diff-highlight.comment-removed {
            background: #ffebee;
            color: #c62828;
            border: 1px solid #ffcdd2;
            font-style: italic;
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .header h1 {
            color: #333;
            margin-bottom: 10px;
        }
        
        .header p {
            color: #666;
            font-size: 16px;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>JSON 差异对比功能测试</h1>
        <p>测试智能修复的差异对比和高亮功能</p>
    </div>

    <div class="test-container">
        <div class="test-title">测试 1: 单引号转双引号</div>
        <div class="test-description">测试单引号转双引号的差异高亮</div>
        <textarea class="test-input" id="test1">{
  name: 'John Doe',
  age: 30,
  city: 'New York',
  hobbies: ['reading', 'swimming'],
  active: true
}</textarea>
        <button class="test-button" onclick="testDiff(1)">测试差异对比</button>
        <div id="result1" class="diff-result" style="display: none;"></div>
    </div>

    <div class="test-container">
        <div class="test-title">测试 2: 未引用属性名</div>
        <div class="test-description">测试未引用属性名的差异高亮</div>
        <textarea class="test-input" id="test2">{
  name: "John",
  age: 30,
  city: "New York",
  isActive: true,
  hobbies: ["reading", "swimming"]
}</textarea>
        <button class="test-button" onclick="testDiff(2)">测试差异对比</button>
        <div id="result2" class="diff-result" style="display: none;"></div>
    </div>

    <div class="test-container">
        <div class="test-title">测试 3: 尾随逗号</div>
        <div class="test-description">测试尾随逗号的差异高亮</div>
        <textarea class="test-input" id="test3">{
  "name": "John",
  "age": 30,
  "hobbies": [
    "reading",
    "swimming",
  ],
  "address": {
    "street": "123 Main St",
    "city": "New York",
  },
}</textarea>
        <button class="test-button" onclick="testDiff(3)">测试差异对比</button>
        <div id="result3" class="diff-result" style="display: none;"></div>
    </div>

    <div class="test-container">
        <div class="test-title">测试 4: 注释处理</div>
        <div class="test-description">测试注释移除的差异高亮</div>
        <textarea class="test-input" id="test4">{
  // 用户信息
  "name": "John Doe",
  "age": 30,
  /* 地址信息 */
  "address": {
    "street": "123 Main St",
    "city": "New York"
  },
  // 爱好列表
  "hobbies": ["reading", "swimming"]
}</textarea>
        <button class="test-button" onclick="testDiff(4)">测试差异对比</button>
        <div id="result4" class="diff-result" style="display: none;"></div>
    </div>

    <div class="test-container">
        <div class="test-title">测试 5: 复杂错误组合</div>
        <div class="test-description">测试多种错误的差异高亮</div>
        <textarea class="test-input" id="test5">{
  // 用户数据
  name: 'John Doe',
  age: 30,
  email: john.doe@example.com,
  isActive: true,
  hobbies: [
    'reading',
    'swimming',
  ],
  address: {
    street: '123 Main St',
    city: 'New York',
    zipCode: 10001,
  },
  // 额外信息
  metadata: {
    createdAt: '2023-01-01',
    updatedAt: '2023-12-01',
  },
}</textarea>
        <button class="test-button" onclick="testDiff(5)">测试差异对比</button>
        <div id="result5" class="diff-result" style="display: none;"></div>
    </div>

    <script src="jsonrepair.js"></script>
    <script>
        // 模拟差异对比功能
        function generateDiff(original, repaired) {
            const stats = {
                quotes: 0,
                commas: 0,
                comments: 0,
                changed: 0
            };

            const originalLines = original.split('\n');
            const repairedLines = repaired.split('\n');
            
            let originalHighlighted = '';
            let repairedHighlighted = '';
            
            const maxLines = Math.max(originalLines.length, repairedLines.length);
            
            for (let i = 0; i < maxLines; i++) {
                const originalLine = originalLines[i] || '';
                const repairedLine = repairedLines[i] || '';
                
                if (originalLine !== repairedLine) {
                    // 检测注释移除
                    if (isCommentLine(originalLine) && !isCommentLine(repairedLine)) {
                        stats.comments++;
                        originalHighlighted += highlightComment(originalLine) + '\n';
                        repairedHighlighted += repairedLine + '\n';
                        continue;
                    }
                    
                    // 检测引号修复
                    const quoteDiff = detectQuoteChanges(originalLine, repairedLine);
                    if (quoteDiff.changed) {
                        stats.quotes += quoteDiff.count;
                        originalHighlighted += quoteDiff.originalHighlighted + '\n';
                        repairedHighlighted += quoteDiff.repairedHighlighted + '\n';
                        continue;
                    }
                    
                    // 检测逗号修复
                    const commaDiff = detectCommaChanges(originalLine, repairedLine);
                    if (commaDiff.changed) {
                        stats.commas += commaDiff.count;
                        originalHighlighted += commaDiff.originalHighlighted + '\n';
                        repairedHighlighted += commaDiff.repairedHighlighted + '\n';
                        continue;
                    }
                    
                    // 检测属性名修复
                    const propertyDiff = detectPropertyChanges(originalLine, repairedLine);
                    if (propertyDiff.changed) {
                        stats.changed += propertyDiff.count;
                        originalHighlighted += propertyDiff.originalHighlighted + '\n';
                        repairedHighlighted += propertyDiff.repairedHighlighted + '\n';
                        continue;
                    }
                    
                    // 其他变更
                    stats.changed++;
                    originalHighlighted += highlightChanged(originalLine) + '\n';
                    repairedHighlighted += highlightChanged(repairedLine) + '\n';
                } else {
                    originalHighlighted += originalLine + '\n';
                    repairedHighlighted += repairedLine + '\n';
                }
            }
            
            return {
                stats,
                originalHighlighted: originalHighlighted.trim(),
                repairedHighlighted: repairedHighlighted.trim()
            };
        }

        function isCommentLine(line) {
            const trimmed = line.trim();
            return trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.includes('*/');
        }

        function highlightComment(line) {
            return line.replace(/(\/\/.*$|\/\*[\s\S]*?\*\/)/g, '<span class="diff-highlight comment-removed">$1</span>');
        }

        function detectQuoteChanges(original, repaired) {
            const changes = {
                changed: false,
                count: 0,
                originalHighlighted: original,
                repairedHighlighted: repaired
            };

            const singleQuoteRegex = /'([^']*)'/g;
            let match;
            let count = 0;
            
            while ((match = singleQuoteRegex.exec(original)) !== null) {
                count++;
            }
            
            if (count > 0) {
                changes.changed = true;
                changes.count = count;
                changes.originalHighlighted = original.replace(/'([^']*)'/g, '<span class="diff-highlight quote-fixed">\'$1\'</span>');
                changes.repairedHighlighted = repaired.replace(/"([^"]*)"/g, '<span class="diff-highlight quote-fixed">"$1"</span>');
            }

            return changes;
        }

        function detectCommaChanges(original, repaired) {
            const changes = {
                changed: false,
                count: 0,
                originalHighlighted: original,
                repairedHighlighted: repaired
            };

            const trailingCommaRegex = /,(\s*[}\]])/g;
            let match;
            let count = 0;
            
            while ((match = trailingCommaRegex.exec(original)) !== null) {
                count++;
            }
            
            if (count > 0) {
                changes.changed = true;
                changes.count = count;
                changes.originalHighlighted = original.replace(/,(\s*[}\]])/g, '<span class="diff-highlight comma-fixed">,$1</span>');
                changes.repairedHighlighted = repaired;
            }

            return changes;
        }

        function detectPropertyChanges(original, repaired) {
            const changes = {
                changed: false,
                count: 0,
                originalHighlighted: original,
                repairedHighlighted: repaired
            };

            const unquotedPropertyRegex = /(\s*)(\w+)(\s*):/g;
            let match;
            let count = 0;
            
            while ((match = unquotedPropertyRegex.exec(original)) !== null) {
                count++;
            }
            
            if (count > 0) {
                changes.changed = true;
                changes.count = count;
                changes.originalHighlighted = original.replace(/(\s*)(\w+)(\s*):/g, '$1<span class="diff-highlight changed">$2</span>$3:');
                changes.repairedHighlighted = repaired.replace(/(\s*)"(\w+)"(\s*):/g, '$1<span class="diff-highlight changed">"$2"</span>$3:');
            }

            return changes;
        }

        function highlightChanged(line) {
            return `<span class="diff-highlight changed">${escapeHtml(line)}</span>`;
        }

        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        function testDiff(testNumber) {
            const input = document.getElementById(`test${testNumber}`).value;
            const resultDiv = document.getElementById(`result${testNumber}`);
            
            try {
                // 检查 jsonrepair 库是否可用
                if (typeof JSONRepair === 'undefined' || typeof JSONRepair.jsonrepair !== 'function') {
                    resultDiv.innerHTML = '<div class="diff-header">错误: 智能修复库未加载</div>';
                    resultDiv.style.display = 'block';
                    return;
                }

                // 执行修复
                const repaired = JSONRepair.jsonrepair(input);
                
                // 验证修复结果
                JSON.parse(repaired);
                
                // 生成差异对比
                const diffResult = generateDiff(input, repaired);
                
                // 显示差异统计
                const statsHtml = `
                    <div class="diff-stats">
                        <div class="diff-stat-item">
                            <span>修复统计:</span>
                        </div>
                        <div class="diff-stat-item">
                            <span class="diff-stat-badge quotes">引号: ${diffResult.stats.quotes}</span>
                            <span class="diff-stat-badge commas">逗号: ${diffResult.stats.commas}</span>
                            <span class="diff-stat-badge comments">注释: ${diffResult.stats.comments}</span>
                            <span class="diff-stat-badge changed">变更: ${diffResult.stats.changed}</span>
                        </div>
                    </div>
                `;
                
                // 显示差异结果
                resultDiv.innerHTML = `
                    <div class="diff-header">差异对比结果</div>
                    ${statsHtml}
                    <div class="diff-content">
                        <div class="diff-section original">
                            <strong>修复前:</strong>
                            ${diffResult.originalHighlighted}
                        </div>
                        <div class="diff-section repaired">
                            <strong>修复后:</strong>
                            ${diffResult.repairedHighlighted}
                        </div>
                    </div>
                `;
                
                resultDiv.style.display = 'block';
                
            } catch (error) {
                resultDiv.innerHTML = `
                    <div class="diff-header">修复失败</div>
                    <div class="diff-content">
                        <div class="diff-section original">
                            <strong>错误信息:</strong>
                            ${escapeHtml(error.message)}
                        </div>
                    </div>
                `;
                resultDiv.style.display = 'block';
            }
        }

        // 页面加载完成后检查库是否可用
        document.addEventListener('DOMContentLoaded', function() {
            if (typeof JSONRepair === 'undefined' || typeof JSONRepair.jsonrepair !== 'function') {
                console.warn('JSON 智能修复库未正确加载');
            } else {
                console.log('JSON 智能修复库加载成功');
            }
        });
    </script>
</body>
</html> 